"""
简化的集成测试脚本

测试视频标注系统的核心功能，不需要创建实际视频文件
"""

import os
import shutil
from pathlib import Path
from video_annotation_middleware import VideoAnnotationMiddleware, CMatchVideo


class SimpleIntegrationTest:
    """简化的集成测试类"""
    
    def __init__(self):
        """初始化测试环境"""
        self.test_results_dir = "test_results"
        self.test_videos_dir = "test_videos"
        self.test_passed = 0
        self.test_failed = 0
    
    def setup(self):
        """准备测试环境"""
        print("=" * 60)
        print("准备测试环境...")
        print("=" * 60)
        
        # 创建测试目录
        Path(self.test_videos_dir).mkdir(exist_ok=True)
        Path(self.test_results_dir).mkdir(exist_ok=True)
        
        # 创建模拟的结果文件用于测试搜索功能
        self._create_mock_result_files()
        
        print("✓ 测试环境准备完成\n")
    
    def teardown(self):
        """清理测试环境"""
        print("\n" + "=" * 60)
        print("清理测试环境...")
        print("=" * 60)
        
        # 删除测试目录
        if Path(self.test_results_dir).exists():
            shutil.rmtree(self.test_results_dir)
            print(f"✓ 已删除测试结果目录: {self.test_results_dir}")
        
        if Path(self.test_videos_dir).exists():
            shutil.rmtree(self.test_videos_dir)
            print(f"✓ 已删除测试视频目录: {self.test_videos_dir}")
    
    def _create_mock_result_files(self):
        """创建模拟的结果文件用于测试"""
        print("\n创建模拟结果文件...")
        
        # 结果文件1: 包含person和car
        result1_content = """Frame 1: person(0.95), car(0.87)
Frame 2: person(0.93), dog(0.82)
Frame 3: car(0.91)
Frame 4: person(0.89), car(0.85), dog(0.78)
Frame 5: bicycle(0.76)
"""
        result1_path = Path(self.test_results_dir) / "video1.txt"
        with open(result1_path, 'w', encoding='utf-8') as f:
            f.write(result1_content)
        print(f"  ✓ 创建: video1.txt")
        
        # 结果文件2: 包含dog和cat
        result2_content = """Frame 1: dog(0.92), cat(0.88)
Frame 2: dog(0.90)
Frame 3: cat(0.86), bird(0.75)
Frame 4: dog(0.94), cat(0.89)
"""
        result2_path = Path(self.test_results_dir) / "video2.txt"
        with open(result2_path, 'w', encoding='utf-8') as f:
            f.write(result2_content)
        print(f"  ✓ 创建: video2.txt")
        
        # 结果文件3: 包含car
        result3_content = """Frame 1: car(0.96), truck(0.84)
Frame 2: car(0.93), bus(0.81)
Frame 3: car(0.91)
"""
        result3_path = Path(self.test_results_dir) / "video3.txt"
        with open(result3_path, 'w', encoding='utf-8') as f:
            f.write(result3_content)
        print(f"  ✓ 创建: video3.txt")
        
        # 创建对应的模拟视频文件（空文件）
        for video_name in ["video1.mp4", "video2.mp4", "video3.mp4"]:
            video_path = Path(self.test_videos_dir) / video_name
            video_path.touch()
        print(f"  ✓ 创建模拟视频文件")
    
    def run_test(self, test_name: str, test_func):
        """运行单个测试"""
        print("\n" + "-" * 60)
        print(f"测试: {test_name}")
        print("-" * 60)
        
        try:
            result = test_func()
            if result:
                print(f"✓ 测试通过: {test_name}")
                self.test_passed += 1
            else:
                print(f"✗ 测试失败: {test_name}")
                self.test_failed += 1
        except Exception as e:
            print(f"✗ 测试异常: {test_name}")
            print(f"  错误信息: {str(e)}")
            import traceback
            traceback.print_exc()
            self.test_failed += 1
    
    def test_result_file_format(self):
        """测试1: 验证结果文件格式"""
        result_file = Path(self.test_results_dir) / "video1.txt"
        
        if not result_file.exists():
            print(f"✗ 结果文件不存在: {result_file}")
            return False
        
        print(f"验证结果文件格式: {result_file}")
        
        # 读取结果文件
        with open(result_file, 'r', encoding='utf-8') as f:
            lines = f.readlines()
        
        if not lines:
            print("✗ 结果文件为空")
            return False
        
        print(f"  文件包含 {len(lines)} 行")
        
        # 验证格式：每行应该是 "Frame X: ..." 格式
        valid_format = True
        for i, line in enumerate(lines, 1):
            line = line.strip()
            if not line:
                continue
            if not line.startswith("Frame "):
                print(f"✗ 第{i}行格式不正确: {line}")
                valid_format = False
                break
            print(f"  第{i}行: {line}")
        
        if not valid_format:
            return False
        
        print("✓ 结果文件格式正确")
        return True
    
    def test_keyword_search_person(self):
        """测试2: 搜索关键词 'person'"""
        middleware = VideoAnnotationMiddleware(
            videos_dir=self.test_videos_dir,
            results_dir=self.test_results_dir
        )
        
        keyword = "person"
        print(f"搜索关键词: '{keyword}'")
        
        results = middleware.searchKeyword(keyword)
        
        print(f"  找到 {len(results)} 个匹配的视频")
        
        # 应该只在video1.txt中找到person
        if len(results) != 1:
            print(f"✗ 期望找到1个结果，实际找到{len(results)}个")
            return False
        
        match = results[0]
        print(f"  视频名称: {match.m_videoName}")
        print(f"  匹配次数: {match.m_matchCnt}")
        print(f"  匹配行数: {len(match.m_matchedLines)}")
        
        # 验证匹配次数（video1.txt中person出现3次）
        if match.m_matchCnt != 3:
            print(f"✗ 期望匹配3次，实际匹配{match.m_matchCnt}次")
            return False
        
        # 验证匹配的行
        for line_info in match.m_matchedLines:
            print(f"    第{line_info['line_number']}行: {line_info['content']}")
        
        print("✓ 关键词搜索功能正常")
        return True
    
    def test_keyword_search_car(self):
        """测试3: 搜索关键词 'car'"""
        middleware = VideoAnnotationMiddleware(
            videos_dir=self.test_videos_dir,
            results_dir=self.test_results_dir
        )
        
        keyword = "car"
        print(f"搜索关键词: '{keyword}'")
        
        results = middleware.searchKeyword(keyword)
        
        print(f"  找到 {len(results)} 个匹配的视频")
        
        # 应该在video1.txt和video3.txt中找到car
        if len(results) != 2:
            print(f"✗ 期望找到2个结果，实际找到{len(results)}个")
            return False
        
        for match in results:
            print(f"  - {match.m_videoName}: {match.m_matchCnt} 次匹配")
        
        print("✓ 多视频搜索功能正常")
        return True
    
    def test_keyword_search_dog(self):
        """测试4: 搜索关键词 'dog'"""
        middleware = VideoAnnotationMiddleware(
            videos_dir=self.test_videos_dir,
            results_dir=self.test_results_dir
        )
        
        keyword = "dog"
        print(f"搜索关键词: '{keyword}'")
        
        results = middleware.searchKeyword(keyword)
        
        print(f"  找到 {len(results)} 个匹配的视频")
        
        # 应该在video1.txt和video2.txt中找到dog
        if len(results) != 2:
            print(f"✗ 期望找到2个结果，实际找到{len(results)}个")
            return False
        
        for match in results:
            print(f"  - {match.m_videoName}: {match.m_matchCnt} 次匹配")
        
        print("✓ 关键词搜索功能正常")
        return True
    
    def test_case_insensitive_search(self):
        """测试5: 不区分大小写的搜索"""
        middleware = VideoAnnotationMiddleware(
            videos_dir=self.test_videos_dir,
            results_dir=self.test_results_dir
        )
        
        print("测试不区分大小写的搜索...")
        
        # 搜索相同关键词的不同大小写形式
        keyword_lower = "person"
        keyword_upper = "PERSON"
        keyword_mixed = "Person"
        
        results_lower = middleware.searchKeyword(keyword_lower)
        results_upper = middleware.searchKeyword(keyword_upper)
        results_mixed = middleware.searchKeyword(keyword_mixed)
        
        print(f"  '{keyword_lower}' 搜索结果: {len(results_lower)} 个")
        print(f"  '{keyword_upper}' 搜索结果: {len(results_upper)} 个")
        print(f"  '{keyword_mixed}' 搜索结果: {len(results_mixed)} 个")
        
        # 验证结果数量相同
        if len(results_lower) != len(results_upper) or len(results_lower) != len(results_mixed):
            print("✗ 不同大小写的搜索结果数量不一致")
            return False
        
        # 验证匹配次数相同
        if results_lower and results_upper and results_mixed:
            if (results_lower[0].m_matchCnt != results_upper[0].m_matchCnt or 
                results_lower[0].m_matchCnt != results_mixed[0].m_matchCnt):
                print("✗ 不同大小写的匹配次数不一致")
                return False
        
        print("✓ 不区分大小写搜索功能正常")
        return True
    
    def test_search_results_sorting(self):
        """测试6: 验证搜索结果按匹配次数排序"""
        middleware = VideoAnnotationMiddleware(
            videos_dir=self.test_videos_dir,
            results_dir=self.test_results_dir
        )
        
        print("测试搜索结果排序...")
        
        # 搜索car（在video1和video3中都有，但次数不同）
        results = middleware.searchKeyword("car")
        
        if len(results) < 2:
            print("  - 结果少于2个，跳过排序测试")
            return True
        
        print(f"  找到 {len(results)} 个结果")
        
        # 验证结果按m_matchCnt降序排序
        is_sorted = True
        for i in range(len(results) - 1):
            if results[i].m_matchCnt < results[i + 1].m_matchCnt:
                print(f"✗ 结果未正确排序: 位置{i}的匹配数({results[i].m_matchCnt}) < 位置{i+1}的匹配数({results[i+1].m_matchCnt})")
                is_sorted = False
                break
            print(f"  结果{i+1}: {results[i].m_videoName} - {results[i].m_matchCnt} 次匹配")
        
        if not is_sorted:
            return False
        
        print("✓ 搜索结果正确排序")
        return True
    
    def test_no_results_search(self):
        """测试7: 搜索不存在的关键词"""
        middleware = VideoAnnotationMiddleware(
            videos_dir=self.test_videos_dir,
            results_dir=self.test_results_dir
        )
        
        keyword = "elephant"
        print(f"搜索不存在的关键词: '{keyword}'")
        
        results = middleware.searchKeyword(keyword)
        
        print(f"  找到 {len(results)} 个匹配的视频")
        
        if len(results) != 0:
            print(f"✗ 期望找到0个结果，实际找到{len(results)}个")
            return False
        
        print("✓ 无结果搜索处理正常")
        return True
    
    def test_empty_directory_search(self):
        """测试8: 在空目录中搜索"""
        empty_dir = "empty_results"
        Path(empty_dir).mkdir(exist_ok=True)
        
        try:
            middleware = VideoAnnotationMiddleware(
                videos_dir=self.test_videos_dir,
                results_dir=empty_dir
            )
            
            print("在空结果目录中搜索...")
            
            results = middleware.searchKeyword("person")
            
            print(f"  找到 {len(results)} 个匹配的视频")
            
            if len(results) != 0:
                print(f"✗ 空目录应该返回0个结果，实际返回{len(results)}个")
                return False
            
            print("✓ 空目录搜索处理正常")
            return True
            
        finally:
            if Path(empty_dir).exists():
                shutil.rmtree(empty_dir)
    
    def test_nonexistent_directory_search(self):
        """测试9: 在不存在的目录中搜索"""
        middleware = VideoAnnotationMiddleware(
            videos_dir=self.test_videos_dir,
            results_dir="nonexistent_results"
        )
        
        print("在不存在的目录中搜索...")
        
        results = middleware.searchKeyword("person")
        
        print(f"  找到 {len(results)} 个匹配的视频")
        
        # 应该返回空列表，不应该抛出异常
        if len(results) != 0:
            print(f"✗ 不存在的目录应该返回0个结果，实际返回{len(results)}个")
            return False
        
        print("✓ 不存在目录的搜索处理正常")
        return True
    
    def test_cmatchvideo_structure(self):
        """测试10: 验证CMatchVideo数据结构"""
        middleware = VideoAnnotationMiddleware(
            videos_dir=self.test_videos_dir,
            results_dir=self.test_results_dir
        )
        
        print("验证CMatchVideo数据结构...")
        
        results = middleware.searchKeyword("person")
        
        if not results:
            print("✗ 没有搜索结果")
            return False
        
        match = results[0]
        
        # 验证所有字段都存在
        print(f"  m_videoName: {match.m_videoName}")
        print(f"  m_videoPath: {match.m_videoPath}")
        print(f"  m_resultFile: {match.m_resultFile}")
        print(f"  m_matchCnt: {match.m_matchCnt}")
        print(f"  m_matchedLines: {len(match.m_matchedLines)} 行")
        
        # 验证m_matchedLines结构
        if match.m_matchedLines:
            first_line = match.m_matchedLines[0]
            if 'line_number' not in first_line or 'content' not in first_line:
                print("✗ m_matchedLines结构不正确")
                return False
            print(f"    示例: 第{first_line['line_number']}行 - {first_line['content']}")
        
        # 验证m_matchCnt与m_matchedLines长度一致
        if match.m_matchCnt != len(match.m_matchedLines):
            print(f"✗ m_matchCnt({match.m_matchCnt})与m_matchedLines长度({len(match.m_matchedLines)})不一致")
            return False
        
        print("✓ CMatchVideo数据结构正确")
        return True
    
    def print_summary(self):
        """打印测试总结"""
        print("\n" + "=" * 60)
        print("测试总结")
        print("=" * 60)
        print(f"总测试数: {self.test_passed + self.test_failed}")
        print(f"通过: {self.test_passed}")
        print(f"失败: {self.test_failed}")
        
        if self.test_failed == 0:
            print("\n🎉 所有测试通过！")
        else:
            print(f"\n⚠️  有 {self.test_failed} 个测试失败")
        
        print("=" * 60)
    
    def run_all_tests(self):
        """运行所有集成测试"""
        print("\n" + "=" * 60)
        print("开始集成测试")
        print("=" * 60)
        
        # 准备测试环境
        self.setup()
        
        try:
            # 运行所有测试
            self.run_test("1. 验证结果文件格式", self.test_result_file_format)
            self.run_test("2. 搜索关键词 'person'", self.test_keyword_search_person)
            self.run_test("3. 搜索关键词 'car'", self.test_keyword_search_car)
            self.run_test("4. 搜索关键词 'dog'", self.test_keyword_search_dog)
            self.run_test("5. 不区分大小写搜索", self.test_case_insensitive_search)
            self.run_test("6. 验证搜索结果排序", self.test_search_results_sorting)
            self.run_test("7. 搜索不存在的关键词", self.test_no_results_search)
            self.run_test("8. 在空目录中搜索", self.test_empty_directory_search)
            self.run_test("9. 在不存在的目录中搜索", self.test_nonexistent_directory_search)
            self.run_test("10. 验证CMatchVideo数据结构", self.test_cmatchvideo_structure)
            
        finally:
            # 清理测试环境
            self.teardown()
        
        # 打印测试总结
        self.print_summary()
        
        return self.test_failed == 0


def main():
    """主函数"""
    test = SimpleIntegrationTest()
    success = test.run_all_tests()
    
    # 返回退出码
    exit(0 if success else 1)


if __name__ == "__main__":
    main()
